package com.example.demo001.controller;


import com.example.demo001.common.result.Result;
import com.example.demo001.constant.JwtClaimsConstant;
import com.example.demo001.constant.MessageConstant;
import com.example.demo001.context.BaseContext;
import com.example.demo001.pojo.dto.UserDto;
import com.example.demo001.pojo.dto.UserLoginDto;
import com.example.demo001.pojo.vo.UserVo;
import com.example.demo001.properties.JwtProperties;
import com.example.demo001.service.UserService;
import com.example.demo001.utils.JwtUtil;
import com.example.demo001.utils.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Api(tags = "用户模块")
@Slf4j
public class UserController {


    private final UserService userService;
    private final JwtProperties jwtProperties;
    private final RedisTemplate<String, String> redisTemplate;

    // 使用构造函数注入
    public UserController(UserService userService, JwtProperties jwtProperties, RedisTemplate<String, String> redisTemplate) {
        this.userService = userService;
        this.jwtProperties = jwtProperties;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 注册
     */
    @PostMapping("/register")
    @ApiOperation(value = "注册")
    public Result<Object> register(@Valid @RequestBody UserDto userDto) {
        userService.register(userDto);
        log.info("用户名：{} 注册成功", userDto.getUsername());
        return Result.success(MessageConstant.REGISTER_SUCCESS, null);
    }

    /**
     * 登入
     */
    @PostMapping("/login")
    @ApiOperation(value = "登入")
    public Result<UserVo> login(@Valid @RequestBody UserLoginDto userLoginDto, HttpServletRequest request) {

        UserVo userVo = userService.login(userLoginDto, request);
        //登录成功后，生成jwt令牌
        Map<String, Object> claimsForAccessToken = new HashMap<>();

        claimsForAccessToken.put(JwtClaimsConstant.USERNAME, userLoginDto.getUsername());
        claimsForAccessToken.put(JwtClaimsConstant.RANDOM, RandomUtil.generateRandomNumber());

        // 删除redis中该用户名下的所有token
        redisTemplate.delete(JwtClaimsConstant.TOKEN+userLoginDto.getUsername());

        String accessToken = JwtUtil.createJWT(
                jwtProperties.getSecretKey(),
                claimsForAccessToken);

        redisTemplate.opsForValue().set( JwtClaimsConstant.TOKEN+userLoginDto.getUsername(), accessToken, jwtProperties.getTtl(), TimeUnit.MILLISECONDS);

        if(Objects.isNull(userVo)){
            UserVo userVo1 = new UserVo();
            userVo1.setToken(accessToken);
            return Result.success(MessageConstant.LOGIN_SUCCESS, userVo1);
        }
        userVo.setToken(accessToken);

        log.info("用户名：{} 登入成功 上次登入的 ip为 {} 上次登入的时间为{}", userLoginDto.getUsername(), userVo.getIp(), userVo.getLoginTime());
        log.info("accessToken为 ：{}", accessToken);

        return Result.success(MessageConstant.LOGIN_SUCCESS, userVo);
    }

    /**
     * 退出
     */
    @PostMapping("/logout")
    @ApiOperation(value = "退出")
    public Result<Object> logout() {

        String username = BaseContext.getCurrent();
        userService.logout(username);
        log.info("用户名：{} 退出成功", username);
        return Result.success(MessageConstant.LOGOUT_SUCCESS, null);
    }

    /**
     * 修改密码
     */
    @PutMapping("/updatePassword/{oldPassword}/{newPassword}")
    @ApiOperation(value = "修改密码")
    public Result<Object> updatePassword(
            @ApiParam(value = "原密码", required = true, example = "xk123456")
            @PathVariable String oldPassword,
            @ApiParam(value = "新密码", required = true, example = "xk123456")
            @PathVariable String newPassword) {

        userService.updatePassword(oldPassword, newPassword);
        log.info("用户名：{} 修改密码成功", BaseContext.getCurrent());
        return Result.success(MessageConstant.RESET_PASSWORD_SUCCESS, null);
    }

    /**
     * 修改绑定邮箱
     * 只需要传送邮箱即可
     */
    @PutMapping("/updateEmail/{email}/{code}")
    @ApiOperation(value = "修改绑定邮箱")
    public Result<Object> updateEmail(
            @ApiParam(value = "邮箱", required = true, example = "xiaokun@junyufr.com")
            @PathVariable(value = "email") String email,
            @ApiParam(value = "验证码", required = true, example = "m23456")
            @PathVariable(value = "code") String code) {
        userService.updateEmail(email,code);
        return Result.success(MessageConstant.UPDATE_EMAIL_SUCCESS, null);
    }

    /**
     * 找回密码--> 重置密码，通过邮箱重置 发送验证码
     * 参数  email
     */
    @GetMapping("/sendCode")
    @ApiOperation(value = "发送验证码")
    public Result<Object> sendCode(
            @ApiParam(value = "邮箱", required = true, example = "xiaokun@junyufr.com")
            String email) {
        return userService.sendCode(email);
    }

    /**
     * 找回密码--> 重置密码 通过邮箱发送验证码的重置
     * 参数 username + email + code + newPassword
     */
    @PutMapping("/resetPassword")
    @ApiOperation(value = "找回密码")
    public Result<Object> resetPassword(
            @ApiParam(value = "用户信息", required = true)
            @Valid @RequestBody UserDto userDto) {
        userService.resetPassword(userDto);
        return Result.success(MessageConstant.RESET_PASSWORD_SUCCESS, null);
    }


    /**
     * 查看菜单“登录统计”
     */
    @CrossOrigin
    @GetMapping("/loginStatist")
    @ApiOperation(value = "登录统计")
    public Result<Map<String, List<String>>> loginStatist() {

        Map<String, List<String>> stringArrayListMap = userService.loginStatist();
        return Result.success(stringArrayListMap);
    }


}
